package c.x.jy.service.aspect;

import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;

import com.alibaba.druid.util.StringUtils;
import com.alibaba.fastjson.JSON;

import c.x.jy.common.annotation.IntoSet;
import c.x.jy.common.annotation.SetValue;
import c.x.jy.common.exception.RRException;
import c.x.jy.common.utils.GetClassinfo;
import c.x.jy.service.utils.SpringContextUtils;
import lombok.extern.slf4j.Slf4j;

@SuppressWarnings("all")
@Aspect
@Configuration
@Slf4j
public class DataAspect {
	@Autowired
	private SpringContextUtils springContextUtil;

	@Around("@annotation(intoSet)")
	public Object Around(ProceedingJoinPoint joinPoint, IntoSet intoSet) throws Throwable {
		Object value = null;
		try {
			value = joinPoint.proceed();
			// return value;
		} catch (Exception e) {
			throw e;
		} finally {

		}
		if (value == null)
			return value;
		try {
			log.debug("DataAapect::========>" + JSON.toJSONString(value));
			Object code = GetClassinfo.get(value, "code", null);
			Object data = null;
			if (code != null && !code.equals(0)) {
				return value;
			} else if (code == null) {
				data = value;
			} else {
				data = GetClassinfo.get(value, "list", null);
				if (data == null)
					data = GetClassinfo.get(value, "data", null);
			}

			String[] Includefields = intoSet.Includefields();
			if (data != null && data instanceof Collection) {
				Collection list = (Collection) data;
				list.forEach(o -> setObjectValue(o, Includefields));
			} else if (data != null) {
				setObjectValue(data, Includefields);
			}
			log.debug("DataAapect retVal::========>" + JSON.toJSONString(value));
		} catch (Exception e) {
			log.error("redis error", e);
			throw new RRException("服务异常");
		}
		return value;
	}

	private void setObjectValue(Object o, String... Includefields) {
		List<String> exslist = null;
	     if(o==null)return;
		if (Includefields == null || Includefields.length == 0)return;
		
 
			exslist = Arrays.asList(Includefields);

		Field[] field = o.getClass().getDeclaredFields();
		Field[] field1 = null;
		if (o.getClass().getSuperclass() != null) {
			field1 = o.getClass().getSuperclass().getDeclaredFields();
		}
		int length = field1 == null ? field.length : field.length + field1.length;
		for (int j = 0; j < length; j++) {
			String name = j < field.length ? field[j].getName() : field1[j - field.length].getName();
			if ( ! exslist.contains(name)) 	continue;
			SetValue v = j < field.length ? field[j].getAnnotation(SetValue.class)
					: field1[j - field.length].getAnnotation(SetValue.class);
			if (v == null) 	continue;
			String val = v.parameter();
			Object[] params = null;
			if (!StringUtils.isEmpty(val)) {
				params = new Object[val.split(",").length];
				for (int i = 0; i < params.length; i++) {
					String pv = val.split(",")[i];
					//System.out.println(pv);
					params[i] = pv.contains("#") ? GetClassinfo.getFieldValueByName(pv.substring(1), o) : pv;
				//	System.out.println(params[i]);
					if (params[i] == null)
						return;
				}
			}

			if (StringUtils.isEmpty(v.beanName()) || StringUtils.isEmpty(v.method()))
				return;
			Object serValue = GetClassinfo.invoke(springContextUtil.getBean(v.beanName()), v.method(), null, params);
			log.debug(v.beanName() + "  :  " + v.method() + "  :  " + v.parameter() + " serValue :  " + serValue
					+ " name :  " + name + " v.vType() :  " + v.vType());
			if (serValue != null)
				GetClassinfo.set(o, name, serValue, v.vType());
		}
	}

}
